
package com.stackroute.userservice.controller;

import com.stackroute.userservice.model.User;
import com.stackroute.userservice.service.UserAuthenticationService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


@RestController
@Slf4j
@Api("UserAuthentication API Service")
public class UserAuthenticationController {


	static final long EXPIRATION_TIME = 300000;

	@Autowired
	private UserAuthenticationService authicationService;

	public UserAuthenticationController(UserAuthenticationService authicationService) {
		this.authicationService = authicationService;
	}


	@PostMapping("/register")
	@ApiOperation("Register User")
	@ApiImplicitParam(name = "user",value = "user",required = true,dataTypeClass = User.class)
	public ResponseEntity<User> createUser(@RequestBody User user) throws Exception {
		try {
			authicationService.saveUser(user);
			return new ResponseEntity<User>(user, HttpStatus.CREATED);
		} catch (Exception e) {
			return new ResponseEntity<User>(HttpStatus.CONFLICT);
		}
	}
	@PostMapping("/isAuthenticated")
	@ApiOperation("Authenticated User")
	@ApiImplicitParam(name = "body",value = "{Authorization: XXXXX}",required = true,dataTypeClass = Map.class)
	public ResponseEntity<?> isAuthenticated(HttpServletRequest request,@RequestBody Map body) throws Exception {
		Map<String,Object> data = new HashMap<>();
		Object authorizationBody = body.get("Authorization");
		String authorization = request.getHeader("authorization");
		if(StringUtils.isEmpty(authorization) && StringUtils.isEmpty(authorizationBody)){
			data.put("isAuthenticated",false);
			return new ResponseEntity<>(data,HttpStatus.OK);
		}
		log.debug("CIMATCH authenticated");
		data.put("isAuthenticated",true);
		return new ResponseEntity<>(data,HttpStatus.OK);
	}


	@PostMapping("/login")
	@ApiOperation("User Login")
	@ApiImplicitParam(name = "user",value = "user",required = true,dataTypeClass = User.class)
	public ResponseEntity<?> loginUser(@RequestBody User user) throws Exception {
		User u = authicationService.findByUserIdAndPassword(user.getUserId(), user.getUserPassword());
		if (u == null) {
			return new ResponseEntity<User>(HttpStatus.UNAUTHORIZED);
		}
		Map<String, String> map = new HashMap<>();
		try {
			String jwtToken = getToken(user.getUserId(), user.getUserPassword());
			map.clear();
			map.put("message", "User Successfully Logged In");
			map.put("token", jwtToken);
		} catch (Exception e) {
			map.clear();
			map.put("message", e.getMessage());
			map.put("token", null);
			return new ResponseEntity<>(map, HttpStatus.UNAUTHORIZED);
		}

		return new ResponseEntity<>(map, HttpStatus.OK);

	}

	// Generate JWT token
	@ApiIgnore
	public String getToken(String username, String password) throws Exception {
		String jwtToken = Jwts.builder().setSubject(username).setIssuedAt(new Date())
				.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
				.signWith(SignatureAlgorithm.HS256, "secretkey").compact();
		return jwtToken;
	}

}
